RaspyControl Lab: A fully open-source and real-time remote laboratory for education in automatic control systems using Raspberry Pi and Python

Graphical abstract

Description of hardware and software of the main RLs in comparison with RaspyControl Lab.

Remote Laboratory
Reference Open source hardware Open source software 1. Laborem [11,12] Yes Yes 2. UNILabs [13] No Yes 3. WebLab-Deusto LabsLand [9,10] No Yes 4. Farlabs [16] No No 5. RexLab [14] No Yes 6. RaspyControl Lab (own) [26,27] Yes Yes such as the conditioning circuit for the ultrasonic sensor and the 16-bit Analog-to-Digital Converter (ADC) ADS1115, the motor driver with Pulse Width Modulation (PWM) for the 12 V immersion motor pumps, or the connections with the Raspberry Pi. Thus, this paper describes the open-source hardware and software designed and implemented for the RL RaspyControl Lab. To test the RL, we designed and implemented a low-cost tank control system with its signal conditioning for the Raspberry Pi. Then, the users or students can control the level h of the main tank (T1). To illustrate the hardware design, Fig. (1) shows its overall structure. The remainder of the paper is divided as follows: Section 2 depicts the hardware composed of the control tanks and the signal conditioning circuit with its respective Printed Circuit Board (PCB). Section 3 describes the open software created with a special emphasis on real-time video and the web interface for the users. Section 4 shows the list of design files for software and hardware. Section 5 describes the Bill of Materials (BOM). Sections 6 and 7 show the build and operation instructions for the hardware designed, including a troubleshooting subsection. Section 8 exposes the validation of the RL with the different experiments for the identification and control of the plant. Finally, Section 9 outlines the conclusions and further work of this study.

Hardware description
The main features and advantages of our hardware for educators and students are the following: Scalable and fully open-source platform for educational experiments in automatic control. Low-cost and affordable tank control system to help students to learn and experiment in the field of automatic control systems. User-friendly web interface with real-time video to interact with the hardware designed in Python language. Simple, low-cost, and low-power conditioning circuit for the ultrasonic sensor and ADC (ADS1115) with a maximum of 860 Samples Per Second (SPS).
Before starting with the description of hardware and software components, it is important to mention that we employed the typical convention of control systems in the Laplace (s) and z transform domains to designate the hardware as follows: GðsÞ; GðzÞ: Control plant: Main tank (T1). The variable to control is the level (h). HðsÞ; HðzÞ: Analog ultrasonic sensor with its signal conditioning circuit. CðsÞ; CðzÞ: Controller (P, PI, or PID). RðsÞ; RðzÞ: Setpoint (level reference). YðsÞ; YðzÞ: Control output for the tank (T1)-level (h). EðsÞ; EðzÞ: Error.

Overview
Fig. (2) depicts the overall architecture of RaspyControl Lab. In this case, the hardware consists of the remote experiment that is controlled through a Raspberry Pi 4. To achieve this remote control, the Raspberry Pi has an Apache server installed with both HTTP protocol and the complement known as Web Server Gateway Interface (WSGI) to interact with Python language. The Apache server allows access to the RL and contains the web pages for the students to control the experiment, employing a PC, laptop, tablet, or smartphone. The real-time video of the experiment is encoded from a Raspberry Pi camera using the tool FFmpeg [28] that sends the video frames, which are encapsulated into the Real-time Streaming Transport Protocol (RTSP). The frames are sent to a special open-source and real-time video server installed in the Raspberry Pi known as Janus WebRTC [29,30] that transforms the frames in RTSP protocol towards the standard WebRTC, compatible with browsers such as Google Chrome or Mozilla Firefox. As a concept, Web-based Real-Time Communication (WebRTC) [31,32] is a relatively new standard for real-time peer-to-peer communications that has several advantages for gaming, video streaming, and sensor data feeds.
When the students want to perform identification or control of the plant, they must construct an algorithm in Python language that on one hand, reads the analog value of the ultrasonic sensor (US-016) through the ADC (ADS1115) to identify the current level of the tank, and on the other hand, manages the motor pumps of the tanks with the General-Purpose I/Os (GPIOs) of the Raspberry Pi. The ADC is interfaced to the Raspberry Pi with the protocol I 2 C. After, the algorithm is transferred to the Apache server in the Raspberry Pi for further processing. For the hardware described in this paper, we employed a Local Area Network (LAN) with the scheme of Fig. (2). However, remote access to the experiment could be guaranteed from the same Raspberry Pi with its Domain Name System (DNS) or employing a Learning Management System (LMS) as Moodle with few modifications in the software. We wanted to leave this choice according to the technical requirements of the educators or stakeholders interested in the project. Nonetheless, some suggestions for the Internet access of the experiment are indicated in Section 7.1. To extend the hardware features, each one of its components will be explained in the next subsections.

Control tank system
The control tank system is composed of two cylindrical acrylic tanks (height (h) = 51 cm, diameter(dia) = 20.8 cm, thickness = 4 mm) and two (12 V, 4.8 W) immersion motor pumps with a maximum flow and impulse height of (Q max = 240 L/H, h max = 300 cm), respectively. One acrylic tank (T1) is the control plant GðsÞ with its ultrasonic sensor and conditioning HðsÞ, while the tank (T2) serves as a reservoir. Both tanks count with motor pumps to interchange liquid between them, which are interfaced with flexible plastic hoses. Concerning the ultrasonic sensor (US-016), this is an analog sensor with a measurement range between 2 cm to 300 cm and a resolution of 1 mm. For 1 meter measurement, the formula of sensed distance vs. output voltage of the sensor is given by the expression hðmmÞ ¼ 1024 Ã Vout Vcc , where h is the tank level in mm, and V cc ¼ 5V.    ) shows the overall appearance of the control tank system. Due to the tanks were created by a local manufacturer, we designed the different CAD files in TinkerCAD that are available in the section to design files to aid educators and practitioners in their construction in an easy form.

Signal conditioning circuit
The purpose of the signal conditioning circuit is twofold. On one hand, it allows calibrating the minimum level of detection of the control tank (T1) with the ultrasonic sensor. Because the immersion pumps need a minimum level of liquid to prevent damage, we set this minimum level with a value of 4.5 cm over the base of the tanks (T1,T2) as Fig. (3) depicts. Therefore, the signal conditioning circuit guarantees that to this level, its output is 0 V. On the other hand, the circuit helps to reduce the noise from the sensor because of the Common-Mode Rejection Ratio (Typical CMRR = 76 dB) of the MCP6004. The conditioning circuit is composed of a subtracter made with the operational amplifier (MCP6004), some resistors, and a 10KX trimmer as Fig. (4) illustrates.
Since the resistor values of the subtracter are 10KX (R 1 À R 4 ), the output voltage for this circuit is V out ¼ V OFF À V sens , where V OFF is the adjust voltage with the trimmer, and V sens is the output voltage of the ultrasonic sensor. Nonetheless, if a gain is required for this circuit, the resistor R 1 could be changed. The output voltage generated by the subtracter circuit is directly wired to channel A0 of the ADS1115, even though this device counts with 4 channels bounded in the range The only precaution is not to exceed the 3.3 V for the input (channel A0) of the ADS1115. This can be done with a 3.3 V zener diode such as 1N4728A (D2 in schematic), acting as a limiter in the output of the MCP6004. In the experiment, the 3.3 V value is not exceeded due to the tank height (h) and the voltage output of the ultrasonic sensor. In this case, the control experiment for RaspyControl Lab is a Single-Input Single-Output (SISO) system because only a variable (level) is controlled. However, if new variables need to be added for Multiple-input Multiple-output (MIMO) systems, the circuit can be redesigned to meet these specifications.
The circuit has two power supply options. The MCP6004 and sensor operate with 5 V, whereas the ADS1115 with a 3.3 V. Hence, we separated the power supplies for the signal conditioning circuit and the motor pumps in order to reduce electric noise levels in the system. Besides, the ADS1115 was directly interfaced to 3.3 V and the pins SCL and SDA for the I 2 C protocol in the Raspberry Pi. This design selection was due to the ultrasonic sensor (US-016) is a sensible device whose measurement could be affected by ripple voltages or electric noise. Thus, we employed two switched-mode power supplies as Fig. (6) and Fig. (7) show due to their low ripple voltage (AE0:3V). The power supplies must be attached to the connectors (MCP6004 and ADS1115 IN ) according to the schematic of Fig. (4). Besides, the input S IN in the connector MCP6004 allows to interface the sensor voltage output. With these aspects, we designed a Printed Circuit Board (PCB), which is outlined in Fig. (5) with the dimensions (w = 6.91 cm, h = 5.41 cm). Both the schematic and the PCB were designed in the software Proteus VSM 8.9. (See Fig. (8)).
Regarding the 16-bit ADC (ADS1115), this is an I 2 C ADC with four analog channels to convert, and a Programmable Gain Amplifier (PGA). The ADC1115 is attached to the 3.3 V power supply of the Raspberry Pi as mentioned. The programmable data rate for this device goes from 85 SPS to 860 SPS, which is ideal for the control plant because it is not a fast system. Indeed, as we will see in the section of validation and characterization, the settling time (t s ) of the control plant for h ¼ 40cm is (t s % 262secs). Data from the ADS1115 is read in terms of voltage, employing the Adafruit Python Library (circuitpython adafruit_ads1x15 [33]).

Motor pumps power driver
Each motor pump is controlled through a GPIO (12,13) in the Raspberry Pi with PWM support. The selected PWM frequency was f pwm ¼ 490Hz. The maximum current consumption of each motor pump with a 12 V power supply is I % 0:4A, and the power consumption is (P ¼ 4:8W), which is ideal for the nominal capacity of the motor driver L298 (P ¼ 20W) that is used in the control system. The Duty Cycle (k) of each PWM signal is changed with the controller created by the students. Specifically, the students should use the Python library RPi.GPIO with the following methods, where pwm13 is an object for the pin (GPIO 13) to access the different functions of the library RPi.GPIO: pwm13 = GPIO.PWM(13,490) pwm13.ChangeDutyCycle(50) The first method configures the pin and frequency, while the second changes the duty cycle k in percentage (0-100%). Fig. (6) shows the overall schematic with the motor pump driver (L298) and the Raspberry Pi 4.

Components' Box and camera support
Fig. (7) shows the component box of RaspyControl Lab with its components. In the box are allocated the main hardware components of the control system such as the Raspberry Pi, motor pump driver, signal conditioning circuit, and power supplies. The component box was constructed in acrylic with the following dimensions: (h ¼ 9:8 cm; l ¼ 20 cm, and w ¼ 40 cm).
The components were attached to the box with screws type M3 and M2.5 with their nuts. Regarding the camera, this is an 8MP Raspberry Pi camera interfaced with a flex cable of 2 m. The flex cable was put inside a 0.5-inch PVC pipe with a length of l % 1:2 m, including the vertical segment in which the camera is installed as Fig. (1) depicts. We selected this distance to provide a good video focus on the experiment.

3D model
As described, to facilitate the construction of the tanks, and component's box, and to offer a glance at the component distribution, we created an approximate 3D model of the hardware with all its dimensions in the software TinkerCAD. The link with the model is available in Section 4.

Software description
The software component of RaspyControl Lab is composed of a web interface in which the students and educators can identify the control plant, test the controllers, and easily debug them. The interface has the elements depicted in Fig. (10). In the working area, the students or educators can construct their control algorithms in Python to perform different actions in automatic control such as identification, and both testing and debugging of the controllers. At any moment, the users can see the control plant behavior with the real-time video streamed from the camera installed in the experiment. The video frames encoded in the WebRTC standard through the Janus WebRTC server are shown in the user interface with a maximum bandwidth of 200 Kb/s. The developers or educators are encouraged to change this bandwidth with the instructions of the software repository at any moment according to the features of the network in which the experiment is mounted. The latency experimented in the different experiments that we made, oscillated between 500 ms to 3 s.
When the students finish their algorithms in the working area, they can click on the run button to execute the Python script in the experiment. Likewise, the students or educators can save or upload the scripts created in the interface. At last, the buttons view Python console and plot allow the students to see the Python console of the Raspberry Pi to check errors in the code execution or print information, and plot data of the Python script from the sensor, controller, etc., respectively. The web interface is accessed from a web browser compatible with the WebRTC standard such as Google Chrome or Mozilla Firefox. Only the users must type the IP of the Raspberry Pi in the experiment through the browser, for instance, http://192.162. 5.2, or with the domain name http://raspberrypi. All information of the students' scripts in Python is managed through an Apache Server with the mode WSGI using the HTTP port (80) in the Raspberry Pi. The web interface sends the created Python code by means of a POST query to the Apache server.
Thus, six key open-source library components were used in the creation of the software interface, which are described in Table 2. The Janus WebRTC Server was employed for the real-time video, NodeJS to plot the data of the scripts in real-time with a redis database, Flask to process the scripts created by the students in Python through the HTTP protocol, and at last, ACE code editor was utilized to highlight and edit the statements of the scripts in Python directly in the web interface.
In addition to the previous software components, the instructions for developers that want to replicate the software from scratch are available in the GitHub repository ( https://github.com/Uniminutoarduino/RaspyControlLab). In the same way, the instructions are available in Sections 6 and 7 for educators that only want to start the experiment with the components of hardware and software exposed in this document. Finally, the complete Raspberry Pi OS image ready to be downloaded is available in Section 4 with all software components developed in the study.

Bill of materials
The complete Bill of Materials (BOM) is available in the open repository (https://doi.org/10.5281/zenodo.7500242). Some components, especially those for the tank system were made by a local manufacturer. Please, build these components with your local manufacturer or distributor with the dimensions specified in both the BOM and the 3D TinkerCAD model.
In the design, we used two power supplies for the motor pumps and the signal conditioning circuit. Nonetheless, one power supply can be included to reduce the costs with 12 V and 5 V support. By the same token, the Raspberry Pi 4 (4 GB) can be replaced by another of 2 GB since the RAM consumption of RaspyControl Lab does not exceed this value. Indeed as it is indicated in Section 8.5, the current RAM consumption for the experiment is 290 MB. The total implementation cost was USD 461, but with the previous modifications, the cost could be reduced to USD 420. In the BOM (l = length, h = height, w = width).

Build instructions
In this section, we addressed the build instructions for the hardware and software. Firstly, we indicate the overall instructions. Secondly, we describe the particular instructions for each main component in hardware and software with different images that illustrate the procedure.

Overall instructions
In general terms, the instructions to build the hardware and software are summed up as follows: For hardware: 1. Build the acrylic tanks and components' box with the dimensions and holes depicted in the TinkerCAD 3D model taking into account the 1:10 scale. 2. Put and stick the motor pumps in the acrylic tanks. Attach the hoses to the motor pumps and pass them between the tanks, using the holes in the top part of each tank.   MCP6004 to the PCB of the signal conditioning circuit. Besides, notice that we utilized precision resistors in the PCB (1% tolerance).

Installing the components' box
Open the holes for the M3 screws of the L298 driver, and the signal conditioning circuit in the bottom part of the components' box. Also, open four holes for M3 screws to attach the acrylic box to a wood or acrylic base. Regarding the Raspberry Pi, employ M2.5 screws. To connect the camera support, open a 0.5-inch hole on the front of the components box. Locate the components in the box and take as reference the TinkerCAD 3D model. To assure the components, use either M3 or M2.5 nuts and screws as the orange squares in Fig. (15) depict according to the component.    Make a cable with a 4-pin JST XH connector (2.54 mm pitch) for the ultrasonic sensor with l ¼ 1:5 m. This cable will be attached to the sensor in the top lid of the tank (T1). Make a second cable with a 3-pin JST XH connector (2.54 mm pitch) for the ultrasonic sensor with a l ¼ 30 cm. This last connector will be attached to the PCB of the signal conditioning circuit. Both cables only have a JST XH connector on one side. To make the connections of the 5 V and GND for the sensor for both the (T1) top lid and the signal conditioning circuit, we employed the same terminal block of the L298 driver. Besides, we attached in this terminal block, the power supplies (12 V, 5 V) as Fig. (6) and Fig. (16) show. Pay attention to these power supply connections. Join the V out of the ultrasonic sensor with the respective pin in the 3-pin JST XH connector of the conditioning circuit (See Fig. (17)). Make a cable with a 4-pin JST XH connector (2.54 mm pitch) for interfacing ADS1115 with the Raspberry Pi 4. Solder the wires of this cable to the respective pins in the Raspberry Pi GPIO Tall Header -2 Â 20. Follow the schematic of the signal conditioning circuit, remaining that the ADS1115 is interfaced to the I 2 C protocol in the Raspberry Pi. Also, connect the 3.3 V power supply of the Raspberry Pi to the respective pin of this cable. Attach the motor pump wires to each terminal block in the L298 driver. Make a cable to interface the GPIOs for the PWM control of the motor pumps with the L298 driver. Follow the connections described in Fig. (6), remaining that GPIO12 controls the motor pump for T1 (control plant), while GPIO13 for T2 (reservoir tank). The connections of the motor pumps should have the polarity indicated in Fig. (18).

Build camera support
The camera support was created with PVC pipes and couplings. The instructions to assemble it are the following: Cut three segments of 0.5-inch PVC pipe with l 1 ¼ 78 cm; l 2 ¼ 23:5 cm; l 3 ¼ 6:5 cm, respectively. Specifically, to support the camera, join the segments l 2 ; l 3 with a 0.5-inch rounded elbow coupling pipe. Stick the screws of the acrylic camera support to the PVC (l 3 ) segment as Fig. (19) illustrates. Pass the 2 meters flex cable of the Raspberry Pi camera through the PVC pipes l 2 and l 3 .
To connect the PVC pipe segments (l 1 ) and (l 2 ) use a 0.5-inch T-shaped PVC coupling connector. First pass the flex cable through the l 1 segment, next join the segments. (See Fig. (20)) To connect the PVC pipe of the camera, open a 0.5-inch hole in the front side of the components' box. Attach a 0.5-inch PVC threaded male adapter with a nut to support the PVC pipe l 1 . Pay attention to this part because the weight of the camera support and the PVC pipe could tear or break the acrylic components' box. To avoid this issue, put the PVC support on a desk, chair, etc. (See Fig. (21)) Finally, connect the flex cable to the Raspberry Pi camera connector.

Software installation instructions
In this section, we entailed the software instructions for educators, users, or developers. (See Fig. (23)).  3. To select the micro SD card, click on the button ''choose storage". Next, click on the button ''Write". This process will write the image on your micro SD card. Take into account that your micro SD card should have a minimum size of 32 GB. If there is a size problem with the SD card, use another of 64 GB. Wait for the process to finish. Fig. (22) describes this overall procedure. 4. Insert your micro SD card with the written image in the slot of the Raspberry Pi. Next, plug in the 5 V power supply thereof. The Raspberry Pi OS image contains all software components in order to start up the RaspyControl Lab. 5. To connect the Raspberry Pi to the network, you must have an available router, server, or access point. By default, the Raspberry Pi takes an IP through DHCP protocol, that is, whatever of the previous devices must assign an IP automatically to your Raspberry Pi. However, RaspyControl Lab needs an initial setup configuration, taking as a parameter this IP. To connect your Raspberry Pi to the network, you have two options. The first one is to connect directly your Raspberry Pi to a TV, monitor or similar through the micro HDMI connector. Then,     Fig. (24). The file indexcode.html contains the webpage for the users to interact with the experiment. 7. Go to a terminal and write the command to restart the Apache server: sudo service apache2 restart. At this point, the setup configuration is ready.

Instructions for developers
For developers that want to install all software components from scratch using a custom Raspberry Pi OS image, please see the instructions of the GitHub repository of the project available at https://github.com/Uniminutoarduino/ RaspyControlLab.

Operation instructions
To access and experiment with RaspyControl Lab, follow these instructions: 1. Fill with liquid the tank (T2). Turn on the power supplies (5 V, 12 V). 2. Plug in the DC adapter of the Raspberry Pi. Wait for the Raspberry Pi OS starts. 3. Open a web browser (Google Chrome or Mozilla Firefox) and type the IP of your Raspberry Pi. Also, you can access RaspyControl Lab typing the hostname http://raspberrypi. 4. Check the output voltage of the OP-AMP MCP6004, which is interfaced to the channel A0 of the ADS1115. To the minimum level of T1, the output voltage must be approximately 0 V. Adjust this voltage with the trimmer resistor in the circuit. To achieve this minimum level, use the Python script ''fill_tank.py" to turn on the motor pump of the tank (T1) and reach the minimum level of liquid in this. You can pass liquid between tanks enabling the correct GPIO output. GPIO12 to control the main tank (T1) and GPIO13 for the reservoir tank (T2). 5. To interact with the experiment, you can use the scripts for the different controllers that we have designed. These are available in the main repository of the project. See Section 4. To run any script, click on the run button on the webpage. 6. To see the Python console, click on the button "view python console". You must create a print statement with the text or variable to show in the console. Once you have tested the script in the console, you could click on the stop button to end the script execution. 7. To plot real-time data, we have created a small python library known as plotter. You can import this library in your Python script as follows: import plotter as plot # Library to plot data #You can use any of the following functions as you desire: plot.1m(str(sensor)) #Plot a sample of one sensor, controller, etc. plot.2m(str(sensor),str(sensor2)) #Plot two samples of sensors, controller, etc. #Plot three samples of sensors, controller, etc. plot.3m(str(sensor),str(sensor2),str(sensor3)) The library contains three methods to plot up to three samples of sensors, controllers, etc. The arguments of these methods are data in form of a ''string". Therefore, we employed the method ''str" to transform any numeric variable into a string. If you experiment any trouble with the plotting option, please go to the Section 7.2 for troubleshooting.
If you have a doubt about the previous process, please consult the following tutorials created for the project: https://youtu.be/Vvyo_BSJTMU

Internet connection alternatives for RaspyControl Lab
As mentioned, we tested RaspyControl Lab in a LAN. To provide access to the experiment on the Internet, we suggest the following: 1. The simplest method is to get a public IP for your Raspberry. In this case, change the IP of the Raspberry according to the previous steps in the sections on instructions for educators and developers. Also, take in mind that the hostname of the experiment is raspberrypi. 2. If you already count with an application server and you desire to incorporate RaspyControl Lab into it, please, redirect the IP of RaspyControl Lab to be accessed by it. This can be done using rewrite or redirect rules in the Apache server o Nginx server, possibly installed on your application server. However, take in mind the IP assignation in the sections on instructions for educators and developers. Similarly, if you plan to use a domain or subdomain, you need to use redirect rules in the Apache server o Nginx server to the IP of the Raspberry Pi. Some references to do that can be consulted in [34][35][36][37]. 3. The same system used in RaspyControl Lab was implemented in RaspyLab [21]. In this case, we deployed the remote laboratory in a Virtual Private Server (VPS) with web access through an internet connection to the students. Please, check the previous reference for further information. 4. To build a server with Raspberry Pi to provide an Internet connection to the experiment, please, follow the steps of the GitHub repository of this project. If another server is built on a Linux machine, e.g., on Ubuntu, install each component used in the project, for example, the Janus WebRTC server, etc., according to the instructions provided on the website of each developer for this Linux distribution.

Possible issues and troubleshooting
If you have any doubt about the software component of RaspyControl Lab, consult the GitHub repository https://github.com/Uniminutoarduino/RaspyControlLab and follow the instructions. In some cases, if you configure the IP of the Raspberry Pi from the wireless and wired network settings in the Raspberry Pi OS, the IP could fail. In this case, change the IP of your Raspberry PI again, following the procedure in the video ''Change IP" available above. At last, reboot your Raspberry Pi. Besides, be aware of the version of the browsers Chrome and Firefox to support the standard WebRTC. Please, see this webpage to know the minimum version for those: https://caniuse.com/?search=webrtc.
Another possible issue is regarding the plotting option. We used a redis database to save the values of the data sent from the RL. If the plotting option fails, check both the status of the redis server and the node.js server. In this case, follow these steps: Close the plot window in your web browser. Always that you use this feature, stop sampling with the stop button on the webpage. Open a terminal in the Raspberry Pi OS. Write the command ps aux j grep node to identify the node.js applications running on the Raspberry Pi. Kill the node.js processes using the command sudo kill À9 (process number). Delete all processes listed from the previous command that are linked to the folder HardwareX on the desktop of the Raspberry Pi OS. Reboot your Raspberry Pi. This would fix the problem with the plotting option.
Similarly, if you plan to use a touchscreen monitor on the MIPI DSI display port of the Raspberry Pi, the VNCViewer could show a black screen. In this case, go to step 17 in the software repository of the project to solve this problem. If there is a problem with the ADC (ADS1115), please, check the voltage (3.3 V), the pins for the protocol I 2 C, and their setting in the Raspberry Pi OS.
Finally, as an observation, the video can present some delays of a few milliseconds due to the LAN or Internet connections. This is a proper issue with the Janus WebRTC server and the clients' video connections. In any case, this problem is solved automatically with the stabilization of the video frames over time. If the problem continues, just reload the webpage.

Validation and characterization
The validation process of RaspyControl Lab was made by performing the different steps in automatic control such as identification of the control plant, simulation of the identified model, controller design, and debugging. These stages allowed us to test both the tank control system and the user interface in Python language. Furthermore, the designed Simulink models and the SISO tool sessions from MATLAB R2018b employed in the stage of validation and characterization are available in the open repository of the project. In accompaniment with these models, datasets for the different experiments to contrast the theoretical and empirical data can be found in Section 4.

Plant and conditioning circuit identification
One of the most important steps in automatic control is the identification of the control plant, that is, the mathematical behavior of the control tank system presented in Fig. (3). To identify this behavior, we conducted three experiments in which the tank (T1) was filled from the minimum level (0 cm) to (40 cm) that is the maximum level allowed in the control plant. After, the average of the data for the experiments concerning level (cm) vs. time (secs), and V out of the conditioning circuit vs. level (cm) were plotted such as Figs. (25), (26) illustrate.
Initially, the mathematical expression that rules the behavior of the level of the tank (T1) is given by the following equation: In the expression (2), YðsÞ is the output level of the tank (T1). We change this name to avoid misconceptions with the gain of the signal conditioning circuit HðsÞ. With the previous mathematical expressions in the Laplace domain, we simulated and compared these ones with the real data, employing MATLAB R2018b. Real and modeled data after performing these simulations are closely related.

Open loop modeling and simulation
With the previous mathematical expressions in Laplace domain, we simulated their step response in Simulink from MATLAB. We emulated the flow ðQ Þ of the motor pump as a step whose final value was Q ¼ 47:77 cm 3 sec . Besides, we added a gain of 0.0482 for the sensor and the circuit of signal conditioning to get its output voltage V out (see Fig. (28)).  Notice that in both plots the simulated behavior is similar to the experimental data presented in Figs. (25), (26), which corroborates that the mathematical models in the Laplace domain for the control plant and the conditioning circuit are suitable and match with the real data. With the Simulink model, the next step was the controller design and check the closedloop response for the control plant.

Controller design
For the controller design, we employed the Single-Input, Single-Output (SISO) Tool from MATLAB. Besides, we construct three classical controllers: Proportional (P), Proportional-Integral (PI), and Proportional-Integral-Derivative (PID) for the control system and we compared their performance. All controllers were implemented in both Arduino and in the web interface constructed for the RL in Python language. We used Arduino in the initial stages of development of the hardware and software components to check the stability of the controllers and agile the process of deployment of the control plant. Regarding the Proportional Controller (P), we started with an experimental Proportional Constant K p ¼ 30. This value is the lower limit in which the plant did not respond to the controller compensation. After a progressive increase of K p from 30 to 100, we found this last value as the optimum for the response of the plant. Then, we simulated the closed-loop step response with the P controller in Simulink with the schematic illustrated in Fig. (30).
In green is represented the P controller with a normalization gain of 0.08333 which is equivalent to 1/12 V. This relation maps the output of the controller to a range between 0-12 V for the driver L298 because the motor pump works with these voltages, which are equivalent for the PWM signal to a duty cycle k in the range (06k 1). In blue appears the maximum flow  Q max of the motor pump found previously, while in gray is the set point (level desired) for the plant. Fig. (31) shows the closed-loop response for the plant with the P controller and a set point (h ¼ 15cm).
A similar procedure was performed for the PI and PID controllers. For these cases, we utilized directly SISO tool from MATLAB. As for the PI controller, we added an integrator and a real zero at the location À0.008333 to this tool, starting from the expression for a PI controller in the Laplace domain in the Eq. (4). The real zero was found after several iterations and comparations of the closed-loop response with the SISO tool. In the Eq. (4), K p is the proportional constant, and K i is the integral constant.
The SISO tool produced the expression in Eq. (5) with the previous parameters. The Bode, root locus, and step response plots illustrated in Fig. (32) show the system stability and an overshoot percentage of 19.4%.
C Pi ðsÞ ¼ 120 Ã ðs þ 0:008333Þ s ; a ¼ 0:008333; K p ¼ 120; However, previous values yielded a slower response of the plant and an overshoot of approximately 20%. To compensate this fact, we iterated until to find a set of optimum values for K p ¼ 350; K i ¼ 2:9. With the initial values of K p ¼ 120; K i % 1, we simulated the response of the plant according to the scheme in Fig. (33). Nonetheless, the experimental data with the values of K p and K i taken in the iterations are available in the dataset of the project in Section 4. (See Fig. (34)) Concerning the PID controller, we took the following expression for its design: where K d is the derivative constant. Based on the previous values for the PI controller, we added a second real zero at the location À0.018 in the SISO tool, ensuring do not exceed an overshoot of 10%. This second real zero led to the following expression for the PID controller: Nevertheless, a value of K d ¼ 6720 is very large and it is not suitable for implementation purposes. Thus, we selected a value of K d ¼ 120 to test the PID controller and observe its response. This K d value yields to K i ¼ 21:6 and K p ¼ 1459. Figs. (35), (36) describe the closed-loop PID scheme and its step response with the previous values.

Controller implementation
For the implementation, each one of the previous controllers (P, PI, PID) in the Laplace domain were transformed into Z transform for their discretization. So, we employed the method Zero-Order Holder (ZOH) for this aim with a sampling time T s ¼ 0:6secs. Table (3) represents the Laplace domain and the Z transform equivalents for the controllers. In the table,   Once the controllers were transformed to the z domain, we found the respective difference equations for them in order to perform their implementation in Python. Table (4) shows the difference equations in each case. In the table, CðkTÞ; EðkTÞ are the discretized output of the controller with its error, EðkT À 1Þ is the previous sample of the error eðkTÞ in a sampling time T s before, EðkT À 2Þ is the error two samples before, and so forth. The same applies to the output of the controller CðzÞ.   With the difference equations in Table (4), we implemented each controller in Python language, utilizing the web user interface. Algorithm. (1) shows a sample of one script created for the PI controller with a setpoint rðtÞ ¼ 25cm. For instance, line 25 in the algorithm. (1) shows the difference equation for this controller according to the expression of Table (4) with a change in the Proportional Constant of K p ¼ 350 for better performance. Besides, lines 26-34 describe the limits (saturationanti windup) for the controller with the PWM for the motor pump on GPIO 12. After, we compared the closed-loop step response and the settling time t s of each controller implementation for a given setpoint (rðtÞ ¼ 40cm) as Fig. (37) depicts. In this figure, the PID controller had the worst performance (t s % 337secs), while the PI controller with the ZOH method had the best performance (t s % 243secs). Similarly, the PI controller with the Tustin method (bilinear transform) obtained a similar performance to the PI with the ZOH method. Each one of the Python scripts for the controllers with their comments is available in the repository in Section 4. Listing 1: Python example of PI controller (ZOH method).

Controller Z Transform (z) Difference Equation (kT)
Proportional Controller (P) Even though we described the results for a setpoint rðtÞ ¼ 40cm, we made several tests, starting from a set point of rðtÞ ¼ 1cm with the different controllers (P, PI, PID), which are illustrated in Fig. (38). In all experiments, the PID controller got the lower performance of all controllers implemented. The previous results demonstrate that the processes of identification, design and implementation of the controllers are congruent and suitable for the hardware and software created in this study.

RAM Memory consumption of the Raspberry Pi
To finish the tests of the hardware designed, we checked the RAM consumption of the Raspberry Pi with the real-time video and the execution of the digital controllers (P, PI, PID), employing the tool htop [38] for Linux-based systems. Fig. (39) shows the results produced by this interactive process viewer. In this, the maximum RAM consumption was 290 MB from a 4 GB total memory of the Raspberry Pi with the main software components such as the Janus WebRTC server or the video streaming running (see green lines). This fact demonstrates that the experiment can run in a Raspberry Pi with 2 GB of RAM or less, which can help to reduce the costs of implementation and deployment of the experiment.

Conclusions and further work
In this article, we described the hardware and software components of the real-time remote laboratory RaspyControl Lab. We planned this laboratory to provide a high-quality and low-cost experimentation tool that any educator and student can build and employ to teach and learn automatic control systems, utilizing Python language. In general terms, the cost of RaspyControl Lab could oscillate between USD 420 to USD 461, changing the components mentioned in the section of the Bill of Materials (BOM). Besides, all hardware and software components are available in the repositories built for the project under the respective Creative Commons Attribution-ShareAlike license. The different validation experiments demonstrated that RaspyControl Lab is feasible and suitable to learn and experiment in control systems with few and low-cost hardware and software components. We hope that the software and hardware that we have created, help to bring the area of automatic control systems closer to students and stakeholders who wish to learn and experiment much more about the concepts of this area. Further work will be focused on creating new real-time experiments for automatic control and programming using Python language, starting from the software and hardware created in this study.

Declaration of Competing Interest
The authors declare that they have no known competing financial interests or personal relationships that could have appeared to influence the work reported in this paper.